using UnityEngine;
using DLib.BehaviorTree;
using DLib.BehaviorTree.Tasks;

/// <summary>
/// AI角色示例
/// 展示如何在游戏中使用行为树实现AI决策
/// 包含血量管理、玩家检测、行为优先级等
/// </summary>
public class AICharacter : MonoBehaviour
{
    /// <summary>行为树组件引用</summary>
    public BehaviorTree behaviorTree;
    
    /// <summary>当前血量</summary>
    public float health = 100f;
    
    /// <summary>最大血量</summary>
    public float maxHealth = 100f;
    
    /// <summary>检测范围</summary>
    public float detectionRange = 10f;
    
    /// <summary>玩家Transform引用</summary>
    public Transform player;
    
    /// <summary>玩家是否在检测范围内</summary>
    public bool isPlayerInRange = false;
    
    /// <summary>是否处于低血量状态</summary>
    public bool isLowHealth = false;

    /// <summary>
    /// Unity Start方法
    /// 初始化AI角色并创建行为树
    /// </summary>
    void Start()
    {
        // 创建行为树实例
        if (behaviorTree == null)
        {
            behaviorTree = new BehaviorTree();
        }

        // 创建AI行为树
        CreateAITree();
    }

    /// <summary>
    /// Unity Update方法
    /// 更新AI状态并手动更新行为树
    /// </summary>
    void Update()
    {
        // 更新AI状态
        UpdateAIState();
        
        // 手动更新行为树
        if (behaviorTree.isRunning && behaviorTree.root != null)
        {
            NodeState state = behaviorTree.root.Evaluate();
            
            if (state != NodeState.Running)
            {
                behaviorTree.isRunning = false;
                Debug.Log($"AI Behavior Tree completed with state: {state}");
            }
        }
    }

    /// <summary>
    /// 创建AI行为树
    /// 实现具有优先级的行为决策系统
    /// </summary>
    void CreateAITree()
    {
        // 创建AI行为树
        Selector rootSelector = new Selector();

        // 优先级1：逃跑（低血量时）- 最高优先级
        Sequence fleeSequence = new Sequence();
        fleeSequence.AddChild(new CheckLowHealthTask(this));
        fleeSequence.AddChild(new LogTask("血量过低，开始逃跑", 0.5f));
        fleeSequence.AddChild(new WaitTask(3f));
        fleeSequence.AddChild(new LogTask("逃跑完成", 0.5f));

        // 优先级2：攻击玩家
        Sequence attackSequence = new Sequence();
        attackSequence.AddChild(new CheckPlayerInRangeTask(this));
        attackSequence.AddChild(new LogTask("发现玩家，开始攻击", 0.5f));
        
        // 攻击选择器 - 尝试不同的攻击策略
        Selector attackSelector = new Selector();
        attackSelector.AddChild(new RandomTask(0.7f)); // 70%概率攻击成功
        attackSelector.AddChild(new LogTask("攻击失败", 0.5f));
        
        attackSequence.AddChild(attackSelector);
        attackSequence.AddChild(new LogTask("攻击完成", 0.5f));

        // 优先级3：巡逻
        Sequence patrolSequence = new Sequence();
        patrolSequence.AddChild(new LogTask("开始巡逻", 0.5f));
        patrolSequence.AddChild(new WaitTask(2f));
        patrolSequence.AddChild(new LogTask("巡逻完成", 0.5f));

        // 优先级4：休息（最低优先级）
        Sequence restSequence = new Sequence();
        restSequence.AddChild(new LogTask("开始休息", 0.5f));
        restSequence.AddChild(new WaitTask(1f));
        restSequence.AddChild(new LogTask("休息完成", 0.5f));

        // 添加所有行为到根选择器
        // 选择器会按顺序尝试执行，直到找到一个可以执行的行为
        rootSelector.AddChild(fleeSequence);
        rootSelector.AddChild(attackSequence);
        rootSelector.AddChild(patrolSequence);
        rootSelector.AddChild(restSequence);

        // 设置根节点
        behaviorTree.SetRoot(rootSelector);
    }

    /// <summary>
    /// 更新AI状态
    /// 检查玩家距离和血量状态
    /// </summary>
    void UpdateAIState()
    {
        // 检查玩家是否在检测范围内
        if (player != null)
        {
            float distance = Vector3.Distance(transform.position, player.position);
            isPlayerInRange = distance <= detectionRange;
        }

        // 检查是否处于低血量状态（30%血量以下）
        isLowHealth = health < maxHealth * 0.3f;
    }

    /// <summary>
    /// Unity OnGUI方法
    /// 显示AI状态界面
    /// </summary>
    void OnGUI()
    {
        // 创建GUI区域
        GUILayout.BeginArea(new Rect(10, 250, 300, 150));
        
        // 显示AI状态信息
        GUILayout.Label("AI Character Status", GUI.skin.box);
        GUILayout.Label($"Health: {health}/{maxHealth}");
        GUILayout.Label($"Player In Range: {isPlayerInRange}");
        GUILayout.Label($"Low Health: {isLowHealth}");
        GUILayout.Label($"AI State: {behaviorTree.GetCurrentState()}");
        
        // 结束GUI区域
        GUILayout.EndArea();
    }

    /// <summary>
    /// 模拟受伤
    /// </summary>
    /// <param name="damage">伤害值</param>
    public void TakeDamage(float damage)
    {
        health = Mathf.Max(0, health - damage);
        Debug.Log($"AI took {damage} damage. Health: {health}");
    }

    /// <summary>
    /// 模拟治疗
    /// </summary>
    /// <param name="amount">治疗量</param>
    public void Heal(float amount)
    {
        health = Mathf.Min(maxHealth, health + amount);
        Debug.Log($"AI healed {amount}. Health: {health}");
    }
}

/// <summary>
/// 检查低血量任务
/// 检查AI角色是否处于低血量状态
/// </summary>
public class CheckLowHealthTask : TaskNode
{
    /// <summary>AI角色引用</summary>
    private AICharacter aiCharacter;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="aiCharacter">要检查的AI角色</param>
    public CheckLowHealthTask(AICharacter aiCharacter)
    {
        this.aiCharacter = aiCharacter;
    }

    /// <summary>
    /// 检查低血量状态
    /// </summary>
    /// <returns>如果低血量返回成功，否则返回失败</returns>
    protected override NodeState OnUpdate()
    {
        return aiCharacter.isLowHealth ? NodeState.Success : NodeState.Failure;
    }
}

/// <summary>
/// 检查玩家是否在范围内任务
/// 检查玩家是否在AI的检测范围内
/// </summary>
public class CheckPlayerInRangeTask : TaskNode
{
    /// <summary>AI角色引用</summary>
    private AICharacter aiCharacter;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="aiCharacter">要检查的AI角色</param>
    public CheckPlayerInRangeTask(AICharacter aiCharacter)
    {
        this.aiCharacter = aiCharacter;
    }

    /// <summary>
    /// 检查玩家是否在范围内
    /// </summary>
    /// <returns>如果玩家在范围内返回成功，否则返回失败</returns>
    protected override NodeState OnUpdate()
    {
        return aiCharacter.isPlayerInRange ? NodeState.Success : NodeState.Failure;
    }
} 